<template>
  <div class="statistics-container">
    <div class="page-header">
      <h1 class="page-title">体测统计分析</h1>
      <div class="action-bar">
        <el-button type="primary" @click="refreshData" :loading="loading">
          <el-icon>
            <Refresh />
          </el-icon>
          刷新数据
        </el-button>
      </div>
    </div>

    <!-- 数据加载状态 -->
    <div v-if="loading" class="loading-container">
      <el-skeleton style="width: 100%" animated :rows="10" />
    </div>

    <!-- 数据内容 -->
    <div v-else class="statistics-content">
      <!-- 总体情况卡片 -->
      <div class="stat-section">
        <h2 class="section-title">总体情况</h2>
        <div class="stat-cards">
          <el-card class="stat-card">
            <div class="stat-card-content">
              <div class="stat-icon student-icon">
                <el-icon>
                  <User />
                </el-icon>
              </div>
              <div class="stat-info">
                <div class="stat-value">{{ overallData.totalStudents || 0 }}</div>
                <div class="stat-label">学生总数</div>
              </div>
            </div>
          </el-card>

          <el-card class="stat-card">
            <div class="stat-card-content">
              <div class="stat-icon tested-icon">
                <el-icon>
                  <Check />
                </el-icon>
              </div>
              <div class="stat-info">
                <div class="stat-value">{{ overallData.testedStudents || 0 }}</div>
                <div class="stat-label">参测人数</div>
              </div>
            </div>
          </el-card>

          <el-card class="stat-card">
            <div class="stat-card-content">
              <div class="stat-icon rate-icon">
                <el-icon>
                  <DataAnalysis />
                </el-icon>
              </div>
              <div class="stat-info">
                <div class="stat-value">{{ formatPercent(overallData.participationRate) }}</div>
                <div class="stat-label">参测率</div>
              </div>
            </div>
          </el-card>

          <el-card class="stat-card">
            <div class="stat-card-content">
              <div class="stat-icon pass-icon">
                <el-icon>
                  <CircleCheck />
                </el-icon>
              </div>
              <div class="stat-info">
                <div class="stat-value">{{ formatPercent(overallData.overallPassRate) }}</div>
                <div class="stat-label">总体合格率</div>
              </div>
            </div>
          </el-card>
        </div>
      </div>

      <!-- 男女学生统计图表 -->
      <div class="stat-section">
        <h2 class="section-title">男女学生统计</h2>
        <div class="chart-row">
          <el-card class="chart-card" style="flex: 1">
            <div id="genderDistributionChart" class="chart-container"></div>
          </el-card>
          <el-card class="chart-card" style="flex: 1">
            <div id="genderParticipationChart" class="chart-container"></div>
          </el-card>
        </div>
      </div>

      <!-- 各项目合格率统计 -->
      <div class="stat-section">
        <h2 class="section-title">项目合格率统计</h2>
        <el-card>
          <div id="itemPassRateChart" class="chart-container" style="height: 400px"></div>
        </el-card>
      </div>

      <!-- 成绩等级分布 -->
      <div class="stat-section">
        <h2 class="section-title">成绩区间分布</h2>
        <el-card>
          <div class="chart-header">
            <el-select v-model="selectedItemId" placeholder="请选择项目" @change="handleItemChange" :loading="loading">
              <el-option v-for="item in gradeDistributionData.distribution || []" :key="item.itemId" :label="item.itemName" :value="item.itemId">
              </el-option>
            </el-select>
          </div>
          <div v-if="loading" class="loading-chart">
            <el-skeleton style="width: 100%; height: 400px;" animated :rows="10" />
          </div>
          <div v-else id="scoreDistributionChart" class="chart-container" style="height: 400px; width: 100%;"></div>
        </el-card>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import { User, Check, DataAnalysis, CircleCheck, Refresh } from '@element-plus/icons-vue'
import * as echarts from 'echarts'
import { getAllStatistics } from '@/api/statistics'

// 数据状态
const loading = ref(false)
const overallData = ref({})
const passRateData = ref({})
const gradeDistributionData = ref({})
const selectedItemId = ref(null)

// 图表实例
let charts = {
  genderDistribution: null,
  genderParticipation: null,
  itemPassRate: null,
  scoreDistribution: null
}

// DOM变化监视器
let resizeObserver = null

// 添加重试次数控制变量
const renderAttempts = ref(0)
const maxRenderAttempts = 3

// 获取统计数据
const fetchStatisticsData = async () => {
  loading.value = true
  try {
    const res = await getAllStatistics()

    // 检查响应结构
    if (!res.data) {
      ElMessage.error('数据格式有误，请联系管理员')
      return
    }

    // 使用导入的logStatisticsData函数记录数据详情
    import('@/api/statistics').then(({ logStatisticsData }) => {
      logStatisticsData(res.data)
    })

    overallData.value = res.data.overall || {}
    passRateData.value = res.data.passRate || {}
    gradeDistributionData.value = res.data.gradeDistribution || {}

    // 确保DOM已加载完成后再渲染图表
    setTimeout(() => {
      renderAllCharts()
    }, 300)
  } catch (error) {
    ElMessage.error('获取统计数据失败，请稍后重试')
  } finally {
    loading.value = false
  }
}

// 刷新数据
const refreshData = async () => {
  loading.value = true

  // 清空现有数据
  overallData.value = {}
  passRateData.value = {}
  gradeDistributionData.value = {}

  // 清空图表
  Object.values(charts).forEach(chart => {
    if (chart) {
      chart.clear()
      chart.showLoading({
        text: '加载中...',
        maskColor: 'rgba(255, 255, 255, 0.8)'
      })
    }
  })

  try {
    await fetchStatisticsData()
  } catch (error) {
    ElMessage.error('统计数据加载失败，请稍后重试')
  } finally {
    // 隐藏所有图表的加载状态
    Object.values(charts).forEach(chart => {
      if (chart) {
        chart.hideLoading()
      }
    })
    loading.value = false
  }
}

// 渲染所有图表
const renderAllCharts = () => {
  try {
    renderGenderDistributionChart()
    renderGenderParticipationChart()
    renderItemPassRateChart()

    // 获取所有项目数据
    const allProjects = gradeDistributionData.value.distribution || []

    if (allProjects && allProjects.length > 0) {
      // 如果没有选择项目，则默认选择第一个
      if (!selectedItemId.value && allProjects.length > 0) {
        selectedItemId.value = allProjects[0].itemId
      }

      // 找到选中的项目数据
      const selectedProject = allProjects.find(item => item.itemId === selectedItemId.value) || allProjects[0]

      // 渲染选中项目的成绩分布图表
      renderScoreDistribution(selectedProject)
    }
  } catch (error) {
  }
}

// 项目选择改变时的处理函数
const handleItemChange = (itemId) => {
  selectedItemId.value = itemId

  // 查找选中的项目
  const allProjects = gradeDistributionData.value.distribution || []
  const selectedProject = allProjects.find(item => item.itemId === itemId)

  if (selectedProject) {
    renderScoreDistribution(selectedProject)
  }
}

// 渲染男女学生分布饼图
const renderGenderDistributionChart = () => {
  const chartDom = document.getElementById('genderDistributionChart')
  if (!chartDom) {
    return
  }

  // 如果已存在图表实例，则先销毁
  if (charts.genderDistribution) {
    charts.genderDistribution.dispose()
  }

  try {
    charts.genderDistribution = echarts.init(chartDom)

    // 获取男女学生数量并确保是数值类型
    const maleCount = parseInt(overallData.value.maleCount || 0)
    const femaleCount = parseInt(overallData.value.femaleCount || 0)

    const option = {
      title: {
        text: '男女学生分布',
        left: 'center'
      },
      tooltip: {
        trigger: 'item',
        formatter: '{a} <br/>{b}: {c}人 ({d}%)'
      },
      legend: {
        orient: 'vertical',
        left: 'left',
        data: ['男生', '女生']
      },
      series: [
        {
          name: '性别分布',
          type: 'pie',
          radius: '70%',
          center: ['50%', '60%'],
          data: [
            { value: maleCount, name: '男生' },
            { value: femaleCount, name: '女生' }
          ],
          emphasis: {
            itemStyle: {
              shadowBlur: 10,
              shadowOffsetX: 0,
              shadowColor: 'rgba(0, 0, 0, 0.5)'
            }
          },
          itemStyle: {
            color: function (params) {
              const colors = ['#409EFF', '#FF6B6B']
              return colors[params.dataIndex]
            }
          },
          label: {
            formatter: '{b}: {c}人 ({d}%)'
          }
        }
      ]
    }

    charts.genderDistribution.setOption(option)
  } catch (error) {
  }
}

// 渲染男女参测率对比图
const renderGenderParticipationChart = () => {
  const chartDom = document.getElementById('genderParticipationChart')
  if (!chartDom) {
    return
  }

  // 如果已存在图表实例，则先销毁
  if (charts.genderParticipation) {
    charts.genderParticipation.dispose()
  }

  try {
    charts.genderParticipation = echarts.init(chartDom)

    // 确保数据存在并转换为数值类型 - 使用新的字段名和默认值
    const maleRate = typeof overallData.value.maleParticipationRate === 'number' ?
      overallData.value.maleParticipationRate : 0;
    const femaleRate = typeof overallData.value.femaleParticipationRate === 'number' ?
      overallData.value.femaleParticipationRate : 0;
    const totalRate = typeof overallData.value.participationRate === 'number' ?
      overallData.value.participationRate : 0;

    // 在图表实例准备好后处理数据
    const option = {
      title: {
        text: '男女参测率对比',
        left: 'center'
      },
      tooltip: {
        trigger: 'axis',
        axisPointer: {
          type: 'shadow'
        },
        formatter: (params) => {
          const value = parseFloat(params.data.value).toFixed(1)
          return `${params.name}: ${value}%`
        }
      },
      grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true
      },
      xAxis: {
        type: 'category',
        data: ['男生', '女生', '总体']
      },
      yAxis: {
        type: 'value',
        axisLabel: {
          formatter: (value) => {
            return parseFloat(value).toFixed(1) + '%'
          }
        },
        max: 100
      },
      series: [
        {
          name: '参测率',
          type: 'bar',
          data: [
            {
              value: parseFloat(maleRate).toFixed(1),
              itemStyle: { color: '#409EFF' }
            },
            {
              value: parseFloat(femaleRate).toFixed(1),
              itemStyle: { color: '#FF6B6B' }
            },
            {
              value: parseFloat(totalRate).toFixed(1),
              itemStyle: { color: '#67C23A' }
            }
          ],
          label: {
            show: true,
            position: 'top',
            formatter: (params) => {
              return parseFloat(params.value).toFixed(1) + '%'
            }
          }
        }
      ]
    }

    charts.genderParticipation.setOption(option)
  } catch (error) {
  }
}

// 渲染项目合格率柱状图
const renderItemPassRateChart = () => {
  const chartDom = document.getElementById('itemPassRateChart')
  if (!chartDom) {
    return
  }

  // 如果已存在图表实例，则先销毁
  if (charts.itemPassRate) {
    charts.itemPassRate.dispose()
  }

  try {
    charts.itemPassRate = echarts.init(chartDom)

    const items = passRateData.value.items || []
    const itemNames = items.map(item => item.itemName)
    const passRates = items.map(item => parseFloat(item.passRate))

    const option = {
      title: {
        text: '各项目合格率',
        left: 'center'
      },
      tooltip: {
        trigger: 'axis',
        axisPointer: {
          type: 'shadow'
        },
        formatter: '{b}<br/>合格率: {c}%<br/>合格人数: {d}/{e}'
      },
      grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true
      },
      xAxis: {
        type: 'category',
        data: itemNames,
        axisLabel: {
          interval: 0,
          rotate: 30
        }
      },
      yAxis: {
        type: 'value',
        axisLabel: {
          formatter: (value) => {
            return Math.round(value) + '%'
          }
        },
        max: 100
      },
      series: [
        {
          name: '合格率',
          type: 'bar',
          data: items.map((item, index) => {
            return {
              value: parseFloat(parseFloat(item.passRate).toFixed(2)),
              d: item.passedScores,
              e: item.totalScores,
              itemStyle: {
                color: getPassRateColor(parseFloat(item.passRate))
              }
            }
          }),
          label: {
            show: true,
            position: 'top',
            formatter: (params) => {
              return parseFloat(params.value).toFixed(2) + '%'
            }
          }
        }
      ]
    }

    charts.itemPassRate.setOption(option)
  } catch (error) {
  }
}

// 渲染成绩分布图表 - 使用选中项目的成绩数据
const renderScoreDistribution = (selectedProject) => {
  if (!selectedProject) return

  const chartDom = document.getElementById('scoreDistributionChart')
  if (!chartDom) {
    return
  }

  // 如果已存在图表实例，则先销毁
  if (charts.scoreDistribution) {
    charts.scoreDistribution.dispose()
  }

  try {
    charts.scoreDistribution = echarts.init(chartDom)

    // 检查是否有原始成绩数据
    if (!selectedProject.scores || selectedProject.scores.length === 0) {
      return
    }

    // 根据项目类型生成不同的区间划分
    let intervals = []
    let data = []
    const scores = selectedProject.scores

    // 根据项目类型和单位生成不同的区间和数据
    if (selectedProject.itemType === '计时类') {
      // 计时类项目（跑步等）- 时间越短越好
      // 根据成绩范围生成合适的区间
      generateIntervalData(scores, true, selectedProject.unit)
    } else if (selectedProject.itemType === '计数类') {
      // 计数类项目（引体向上、仰卧起坐等）- 次数越多越好
      generateIntervalData(scores, false, selectedProject.unit)
    } else {
      // 测量类项目（身高、体重、立定跳远等）
      generateIntervalData(scores, false, selectedProject.unit)
    }

    function generateIntervalData(scores, isLowerBetter, unit) {
      // 找出最大值和最小值
      const min = Math.min(...scores)
      const max = Math.max(...scores)

      // 计算区间范围和大小
      let range = max - min
      let intervalCount = 6 // 使用6个区间
      let intervalSize = range / intervalCount

      if (intervalSize <= 0) {
        intervalSize = 1 // 防止所有分数相同时区间大小为0
        intervalCount = 1
      }

      // 生成区间标签和数据
      intervals = []
      data = []
      const counts = new Array(intervalCount).fill(0)

      // 为每个区间创建标签
      for (let i = 0; i < intervalCount; i++) {
        let intervalStart = min + i * intervalSize
        let intervalEnd = i < intervalCount - 1 ? min + (i + 1) * intervalSize : max

        // 针对不同项目类型创建合适的标签
        let label = ''
        if (isLowerBetter) {
          // 计时类 - 值越小越好
          if (selectedProject.unit === '秒') {
            // 针对短跑项目（如50米跑）使用更精确的区间
            if (intervalStart >= 60) {
              // 长跑项目（如800米、1000米）使用分:秒格式
              label = `${formatTimeMinSec(intervalStart)}-${formatTimeMinSec(intervalEnd)}`
            } else {
              // 短跑项目使用秒格式
              label = `${intervalStart.toFixed(1)}-${intervalEnd.toFixed(1)}${unit}`
            }
          } else {
            // 针对长跑项目（如800米、1000米）使用整数区间
            label = `${Math.floor(intervalStart)}-${Math.ceil(intervalEnd)}${unit}`
          }
        } else {
          // 计数类和测量类 - 值越大越好
          if (selectedProject.unit === '次' || selectedProject.unit === '个' || selectedProject.unit === '次/分钟') {
            // 计数类使用整数区间
            label = `${Math.floor(intervalStart)}-${Math.ceil(intervalEnd)}${unit}`
          } else {
            // 测量类使用合适的精度
            label = `${intervalStart.toFixed(1)}-${intervalEnd.toFixed(1)}${unit}`
          }
        }

        intervals.push(label)
      }

      // 计算每个区间内的学生人数
      for (const score of scores) {
        for (let i = 0; i < intervalCount; i++) {
          let intervalStart = min + i * intervalSize
          let intervalEnd = i < intervalCount - 1 ? min + (i + 1) * intervalSize : max + 0.000001 // 加一点点确保最大值被包含

          if (score >= intervalStart && score < intervalEnd) {
            counts[i]++
            break
          } else if (i === intervalCount - 1 && score === max) {
            // 处理最大值恰好在最后一个区间的情况
            counts[i]++
          }
        }
      }

      // 将计数转换为图表数据
      data = counts.map((count, index) => ({
        value: count,
        itemStyle: { color: getIntervalColor(index, intervalCount, isLowerBetter) }
      }))
    }

    // 根据区间位置生成颜色（考虑到是否越低越好）
    function getIntervalColor(index, total, isLowerBetter) {
      const position = index / (total - 1) // 位置从0到1

      if (isLowerBetter) {
        // 计时类项目 - 值越小越好，所以前面区间用绿色，后面区间用红色
        return getColorGradient(1 - position) // 反转颜色
      } else {
        // 计数类和测量类 - 值越大越好，所以前面区间用红色，后面区间用绿色
        return getColorGradient(position)
      }
    }

    // 生成从红到绿的颜色渐变
    function getColorGradient(position) {
      // 从红色(#ff6060)到黄色(#ffbf40)到绿色(#67c23a)的渐变
      if (position < 0.5) {
        // 从红到黄
        const r = 255
        const g = Math.floor(96 + position * 2 * (191 - 96))
        const b = Math.floor(96 + position * 2 * (64 - 96))
        return `rgb(${r}, ${g}, ${b})`
      } else {
        // 从黄到绿
        const p = (position - 0.5) * 2 // 从0到1
        const r = Math.floor(255 - p * (255 - 103))
        const g = Math.floor(191 - p * (191 - 194))
        const b = Math.floor(64 - p * (64 - 58))
        return `rgb(${r}, ${g}, ${b})`
      }
    }

    // 配置图表选项
    const option = {
      title: {
        text: `${selectedProject.itemName}成绩分布`,
        left: 'center'
      },
      tooltip: {
        trigger: 'axis',
        formatter: function (params) {
          return `${params[0].name}: ${params[0].value}人`
        }
      },
      grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true
      },
      xAxis: {
        type: 'category',
        data: intervals,
        axisLabel: {
          interval: 0,
          rotate: 30
        }
      },
      yAxis: {
        type: 'value',
        name: '人数',
        minInterval: 1
      },
      series: [
        {
          name: '人数',
          type: 'line',
          smooth: true,
          data: data,
          areaStyle: {
            opacity: 0.3
          },
          markPoint: {
            data: [
              { type: 'max', name: '最大值' }
            ]
          }
        }
      ]
    }

    charts.scoreDistribution.setOption(option)
  } catch (error) {
  }
}

// 根据合格率获取颜色
const getPassRateColor = (passRate) => {
  if (passRate >= 90) {
    return '#67C23A' // 绿色
  } else if (passRate >= 70) {
    return '#409EFF' // 蓝色
  } else if (passRate >= 60) {
    return '#E6A23C' // 黄色
  } else {
    return '#F56C6C' // 红色
  }
}

// 窗口大小改变时重新调整图表大小
const handleResize = () => {
  Object.values(charts).forEach(chart => {
    chart && chart.resize()
  })
}

// 组件挂载
onMounted(() => {
  nextTick(() => {
    // 获取数据
    fetchStatisticsData()

    // 设置DOM变化监视器
    setupResizeObserver()
  })
  window.addEventListener('resize', handleResize)
})

// 组件卸载前
onBeforeUnmount(() => {
  window.removeEventListener('resize', handleResize)

  // 清理DOM变化监视器
  if (resizeObserver) {
    resizeObserver.disconnect()
    resizeObserver = null
  }

  // 销毁图表实例
  Object.values(charts).forEach(chart => {
    chart && chart.dispose()
  })
})

// 设置DOM变化监视器
const setupResizeObserver = () => {
  if (!window.ResizeObserver) {
    return
  }

  // 创建DOM变化监视器
  resizeObserver = new ResizeObserver(entries => {
    for (const entry of entries) {
      // 查找这个DOM元素对应的图表实例并重绘
      for (const [key, chart] of Object.entries(charts)) {
        if (chart && entry.target.id.includes(key.replace(/([A-Z])/g, '-$1').toLowerCase())) {
          chart.resize()
          break
        }
      }
    }
  })

  // 监视所有图表容器
  const containers = [
    'genderDistributionChart',
    'genderParticipationChart',
    'itemPassRateChart',
    'scoreDistributionChart'
  ]

  for (const id of containers) {
    const el = document.getElementById(id)
    if (el) {
      resizeObserver.observe(el)
    }
  }
}

// 添加格式化函数
const formatPercent = (value) => {
  if (value === undefined || value === null) return '0.00%'
  // 确保为数字
  const num = parseFloat(value)
  if (isNaN(num)) return '0.00%'
  // 格式化为两位小数的百分比
  return num.toFixed(2) + '%'
}

// 格式化时间为分:秒格式的函数
function formatTimeMinSec(seconds) {
  const minutes = Math.floor(seconds / 60)
  const remainingSeconds = Math.round(seconds % 60)
  return `${minutes}'${remainingSeconds.toString().padStart(2, '0')}"`
}
</script>

<style scoped>
.statistics-container {
  padding: 20px;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 24px;
}

.page-title {
  margin: 0;
  font-size: 24px;
  font-weight: 600;
  color: #303133;
}

.statistics-content {
  min-height: 500px;
}

.stat-section {
  margin-bottom: 30px;
}

.section-title {
  font-size: 18px;
  font-weight: 600;
  margin-bottom: 16px;
  color: #303133;
  position: relative;
  padding-left: 12px;
}

.section-title::before {
  content: '';
  position: absolute;
  left: 0;
  top: 4px;
  bottom: 4px;
  width: 4px;
  background-color: #409EFF;
  border-radius: 2px;
}

.stat-cards {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  margin-bottom: 20px;
}

.stat-card {
  flex: 1;
  min-width: 220px;
}

.stat-card-content {
  display: flex;
  align-items: center;
}

.stat-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 60px;
  height: 60px;
  border-radius: 50%;
  margin-right: 16px;
  font-size: 24px;
  color: white;
}

.student-icon {
  background-color: #409EFF;
}

.tested-icon {
  background-color: #67C23A;
}

.rate-icon {
  background-color: #E6A23C;
}

.pass-icon {
  background-color: #F56C6C;
}

.stat-info {
  display: flex;
  flex-direction: column;
}

.stat-value {
  font-size: 24px;
  font-weight: bold;
  color: #303133;
  line-height: 1.2;
}

.stat-label {
  font-size: 14px;
  color: #909399;
  margin-top: 4px;
}

.chart-row {
  display: flex;
  gap: 20px;
  margin-bottom: 20px;
}

.chart-card {
  flex: 1;
}

.chart-container {
  height: 300px;
  width: 100%;
  background-color: #fff;
  position: relative;
  min-height: 300px;
  margin: 10px 0;
}

.loading-container {
  padding: 30px;
  background-color: white;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.chart-header {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 15px;
}

.loading-chart {
  padding: 30px;
  background-color: white;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
</style>